<?php

class MY_Output extends CI_Output {
	const OUTPUT_MODE_NORMAL = 10;
	const OUTPUT_MODE_TEMPLATE = 11;
	
	private $_title = "";
	private $_charset = "utf-8";
	private $_language = "en-us";
	private $_canonical = "";
	private $_meta = array("keywords"=>array(), "description"=>null);
	private $_template = null;
	private $_mode = self::OUTPUT_MODE_NORMAL;
	private $_messages = array("error"=>"", "info"=>"", "debug"=>"");
	private $_output_data = array();
	
	/**
	 * Set the  template that should be contain the output <br /><em><b>Note:</b> This method set the output mode to MY_Output::OUTPUT_MODE_TEMPLATE</em>
	 * 
	 * @uses MY_Output::set_mode()
	 * @param string $template_view
	 * @return void
	 */
	function set_template($template_view){
		$this->set_mode(self::OUTPUT_MODE_TEMPLATE);
		$template_view = str_replace(".php", "", $template_view);
		$this->_template = self::TEMPLATE_ROOT . $template_view; // "/template.php";		
	}
	
	/**
	 * Sets the way that the final output should be handled.<p>Accepts two possible values 	MY_Output::OUTPUT_MODE_NORMAL for direct output
	 * or MY_Output::OUTPUT_MODE_TEMPLATE for displaying the output contained in the specified template.</p>
	 * 
	 * @throws Exception when the given mode hasn't defined. 
	 * @param integer $mode one of the constants MY_Output::OUTPUT_MODE_NORMAL or MY_Output::OUTPUT_MODE_TEMPLATE
	 * @return void
	 */
	function set_mode($mode){
		
		switch($mode){
			case self::OUTPUT_MODE_NORMAL:
			case self::OUTPUT_MODE_TEMPLATE:
				$this->_mode = $mode;
				break;
			default:
				throw new Exception(get_instance()->lang->line("Unknown output mode."));
		}
		
		return;
	}
	
	/**
	 * Set the title of a page, it works only with MY_Output::OUTPUT_MODE_TEMPLATE
	 * 
	 * 
	 * @param string $title
	 * @return void
	 */
	function set_title($title){
		$this->_title = $title;
	}
	
	/**
	 * Append the given string at the end of the current page title
	 * 
	 * @param string $title
	 * @return void
	 */
	function append_title($title){
		$this->_title .= " - {$title}";
	}
	
	/**
	 * Prepend the given string at the bigining of the curent title.
	 * 
	 * @param string $title
	 * @return void
	 */
	function prepend_title($title){
		$this->_title = "{$title} - {$this->_title}";
	}
	
	/**
	 * Sets a canonical url
	 *
	 */
	function set_canonical($uri){
		$this->_canonical = $uri;
	}

	/**
	 * Set keywords
	 *
	 */
	function set_keywords($keywords){
		$this->_meta['keywords'] = $keywords;
	}
	
	/**
	 * Set description
	 *
	 */
	function set_description($description){
		$this->_meta['description'] = $description;
	}
	
//	/**
//	 * Set messages to be passed in the template.
//	 *
//	 */
//	function set_message($message, $type="error"){
//		log_message($type, $message);
//		$this->_messages[$type] .= $message;
//		get_instance()->session->set_flashdata("__messages", serialize($this->_messages));
//	}
	
	/**
	 * (non-PHPdoc)
	 * @see system/libraries/CI_Output#_display($output)
	 */
	function _display($output=''){
		
		if($output=='')
			$output = $this->get_output();
		
		switch($this->_mode){
			case self::OUTPUT_MODE_TEMPLATE:
				$output = $this->get_template_output($output);
				break;
			case self::OUTPUT_MODE_NORMAL:
			default:
				$output = $output;
				break;		
		}
		
		parent::_display($output);
	}
	
	function set_output_data($varname, $value){
		$this->_output_data[$varname] = $value;
	}
	
	private function get_template_output($output){
		
		if(function_exists("get_instance") && !class_exists("CI_Controller")){
			$ci = get_instance();

			$ci->load->driver('cache', 
				array('adapter' => 'apc', 'backup' => 'file')
			);			
			
//			$messages = $ci->session->flashdata("__messages");
//			$this->_messages = $messages!=FALSE ? unserialize($messages) : $this->_messages;				
			
			$inline = $ci->load->get_inline_scripting();

			if($inline["infile"]!=""){
				$checksum = md5($inline["infile"], false);
				$ci->load->driver('cache');
				$ci->cache->save($checksum, $inline["infile"], 5*60);
				$ci->load->js(site_url("js/{$checksum}.js"));
			}

			if( strlen($inline['stripped']) ){
				$inline['unstripped'] .= "\r\n\r\n<script type=\"text/javascript\">{$inline['stripped']}</script>";
			}

			$data = array();

//			$data["errors"] = $this->get_messages("error");
//			$data["info"] = $this->get_messages("info");
//			$data["debug"] = $this->get_messages("debug");
			
			$this->_meta["keywords"] = $this->_meta["keywords"]

			$data["output"] = $output;
			$data["modules"] = $ci->load->get_sections();
			$data["title"] = $this->_title;
			$data["meta"] = $this->_meta;
			$data["language"] = $this->_language;
			$data["charset"] = $this->_charset;
			$data["js"] = $ci->load->get_js_files();
			$data["css"] = $ci->load->get_css_files();
			$data["inline_scripting"] = $inline['unstripped'];
			$data["canonical"] = $this->_canonical;
			
			$data = array_merge($data, $this->_output_data);
			
			$output = $ci->load->view($this->_template, $data, true, true);
		}

		return $output;
	}

	/**
	 * (non-PHPdoc)
	 * @see system/libraries/CI_Output#_display_cache($CFG, $URI)
	 */
	function _display_cache(&$CFG, &$URI){		
		$content_type = "text/html";
		
		$cache_path = ($CFG->item('cache_path') == '') 
			? BASEPATH.'cache/' 
			: $CFG->item('cache_path');
		
		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)){
			return FALSE;
		}

		// Build the file path.  The file name is an MD5 hash of the full URI
		$uri =	$CFG->item('base_url').
				$CFG->item('index_page').
				$URI->uri_string;
				
		$filepath = $cache_path.md5($uri);
		
		if(version_compare(PHP_VERSION, '5.3', '<')){
			if(function_exists('mime_content_type')){
				$content_type = mime_content_type($filepath);
			}			
		}

		if(version_compare(PHP_VERSION, '5.3', '>=')){
			if(function_exists('finfo_open')){
				
				$fi = new finfo();

				$content_type = $fi->file($filepath);
				
			}			
		}

		$this->set_header("Content-Type: {$content_type}");
		
		return parent::_display_cache($CFG, $URI);
	}	
	
}